package com.example.lprxjava;

import android.annotation.SuppressLint;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;

/**
 * Author by lp,on 2021/7/20/020,14:27.
 * Rxjava 转换
 */
public class TransFragement extends BaseFragment {

    private static final String TAG = "TransFragement";

    @Override
    String getTAG() {
        return TAG;
    }

    @Override
    String getTitle() {
        return "RxJava 转换操作符";
    }

    @Override
    int getFragmentLayoutId() {
        return R.layout.trans_frqagment;
    }

    @Override
    void onLoad(View view) {
        textView = view.findViewById(R.id.tv_show);
        create();
        buffer();
        view.findViewById(R.id.btn_test_flatMap).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                test();
            }
        });

    }

    private void create() {
        observable = Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> e) throws Exception {
                Log.i(TAG, "current Thread: " + Thread.currentThread().getName());
                e.onNext("create方式创建...");
            }
        }).map(new Function<Object, Object>() {
            @Override
            public Object apply(Object o) throws Exception {
                return o.toString() + "->经过map 转换";
            }
        }).map(new Function<Object, Object>() {
            @Override
            public Object apply(Object o) throws Exception {
                return o.toString() + "->经过map 转换";
            }
            //flatmap返回的是一个被观察者，作用是用嵌套请求
        }).flatMap(new Function<Object, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(final Object o) throws Exception {
                return Observable.create(new ObservableOnSubscribe<Object>() {
                    @Override
                    public void subscribe(ObservableEmitter<Object> e) throws Exception {
                        e.onNext(o.toString() + " ->经过flatMap转换");
                        e.onComplete();
                    }
                });
            }
            //flatmap可能是无序的，但是concatMap是绝对有序的
        }).concatMap(new Function<Object, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(Object o) throws Exception {
                return Observable.just(o.toString() + "->经过concatMap");
            }
        });
        observable.subscribe(observer);
    }

    private void buffer() {
        //buffer 缓冲区域
        Observable.just("1111", "2222", "3333", "4444", "5555", "6666").buffer(2).subscribe(observer);
    }

    //模拟传统方式获取数据和rxjava获取数据
    @SuppressLint("CheckResult")
    private void test() {
        //传统方式获取数据
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<StudentModel.Student> students = new StudentModel().getStudents();
                System.out.println("-----传统方式获取数据-----");
                for (StudentModel.Student student : students) {
                    for (String book : student.getBooks()) {
                        System.out.println(book);
                    }
                }
                System.out.println("-----获取完成-----");
            }
        }).start();

        //使用rxjva获取数据
        StudentModel studentModel = new StudentModel();
        Observable<String> start = Observable.just("-----rxjava方式获取数据-----");
        Observable<String> end = Observable.just("-----获取完成-----");
        Observable<Object> objectObservable = Observable.fromIterable(studentModel.getStudents()).flatMap(new Function<StudentModel.Student, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(StudentModel.Student student) throws Exception {
                return Observable.fromIterable(student.getBooks());
            }
        });
        Disposable subscribe = Observable.concat(start, objectObservable, end).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {
                System.out.println(o.toString());
                textView.setText(textView.getText() + "\r\n" + o.toString());
            }
        });
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.i(TAG, "onDestroyView: ");

    }

    private class StudentModel {
        private class Student {
            private String name;

            public Student(String name, List<String> books) {
                this.name = name;
                this.books = books;
            }

            private List<String> books;

            public List<String> getBooks() {
                return books;
            }
        }

        public List<Student> getStudents() {
            ArrayList<Student> students = new ArrayList<Student>();
            for (int i = 0; i < new Random().nextInt(10); i++) {
                List<String> books = new ArrayList<String>();
                books.add("book" + i);
                students.add(new Student("name" + i, books));
            }
            return students;
        }
    }
}
